package com.ncr.travel.appmgr.client.presenter;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;
import com.ncr.nep.dashboardcore.rest.client.JSONCallback;
import com.ncr.travel.appmgr.client.Constants;
import com.ncr.travel.appmgr.client.command.GetScreenConfiguration;
import com.ncr.travel.appmgr.client.event.ConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.ConfigChangeHandler;
import com.ncr.travel.appmgr.client.model.ScreenConfigurationFactory;
import com.ncr.travel.appmgr.client.mvp.BasePresenter;
import com.ncr.travel.appmgr.client.mvp.EventBus;
import com.ncr.travel.appmgr.client.service.AppManagerWebService;
import com.ncr.travel.appmgr.client.view.CategoryAndScreenView;
import com.ncr.travel.appmgr.model.shared.ErrorTexts;
import com.ncr.travel.appmgr.model.shared.Product;
import com.ncr.travel.appmgr.model.shared.ScreenConfiguration;
import com.ncr.travel.appmgr.model.shared.TextEntries;
import com.ncr.travel.appmgr.model.shared.TextEntry;

/**
 * @author nd185038
 * 
 */
public class CategoryAndScreenPresenterImpl extends BasePresenter<CategoryAndScreenView> implements CategoryAndScreenPresenter {

	private Product product;
	private ScreenConfiguration screenConfiguration;
    /**
     * Factory for screen config model objects.
     */
	private ScreenConfigurationFactory screenConfigurationFactory;
	
	private final AppManagerWebService webService;

	private final RulePresenter rulePresenter;
	private final TextPresenter textPresenter;
	private final FunctionPresenter functionPresenter;
	private final GraphicsEditorPresenter graphicsEditorPresenter;

	@Inject
	public CategoryAndScreenPresenterImpl(EventBus eventBus, ScreenConfigurationFactory screenConfigurationFactory, CategoryAndScreenView view, AppManagerWebService webService, RulePresenter rulePresenter, TextPresenter textPresenter, FunctionPresenter functionPresenter,
			GraphicsEditorPresenter graphicsEditorPresenter) {
		super(eventBus, view);
		System.out.println("Constructing CategoryAndScreenPresenter");
		this.screenConfigurationFactory = screenConfigurationFactory;
		this.webService = webService;
		this.rulePresenter = rulePresenter;
		this.textPresenter = textPresenter;
		this.functionPresenter = functionPresenter;
		this.graphicsEditorPresenter = graphicsEditorPresenter;
		view.setPresenter(this);
		bind();
	}

	/**
	 * @see com.ncr.travel.appmgr.client.presenter.CategoryAndPresenter#setProduct(com.com.ncr.travel.appmgr.model.shared.Product)
	 */
	@Override
	public void setProduct(final Product product) {
		this.product = product;
	}

	@Override
	public void bind() {
		System.out.println("(CategoryAndScreenPresenter) Called bind()");
		registerHandler(eventBus.addHandler(ConfigChangeEvent.getType(), new ConfigChangeHandler() {
			public void onConfigChanged(ConfigChangeEvent event) {
				ScreenConfiguration screenConfig = event.getScreenConfiguration();
				if (screenConfig != null) {
					screenConfiguration = screenConfig;
				}
			}
		}));
	}

	/* (non-Javadoc)
	 * @see com.ncr.travel.appmgr.client.presenter.CategoryAndPresenter#setPreviewURL(java.lang.String)
	 */
	@Override
	public void setPreviewURL(String url) {
		if (view.getScreenFrame() != null) {
			view.getScreenFrame().setStyleName("screenFrameVisible");
			view.getScreenFrame().setUrl(url);
		}
	}

	/**
	 * Gets called by the MenuCommand object for view the rule screen
	 * 
	 * @param screenName
	 */
	@Override
	public void displayRulesUi() {
		rulePresenter.setScreenConfiguration(screenConfiguration);
		rulePresenter.go(view.getContentWindowWorkPanel());
	}

	/**
	 * Gets called by the MenuCommand object for view the text screen
	 * 
	 * @param screenName
	 */
	@Override
	public void displayTextUi() {
		textPresenter.setScreenConfiguration(screenConfiguration);
		textPresenter.go(view.getContentWindowWorkPanel());
	}

	/**
	 * Gets called by the MenuCommand object for view the function screen
	 * 
	 * @param screenName
	 */
	@Override
	public void displayFunctionsUi() {
		functionPresenter.setScreenConfiguration(screenConfiguration);
		functionPresenter.go(view.getContentWindowWorkPanel());
	}

	/**
	 * Gets called by the MenuCommand object for view the graphics screen
	 * 
	 * @param screenName
	 */
	@Override
	public void displayGraphicsUi() {
		graphicsEditorPresenter.setScreenConfiguration(screenConfiguration);
		graphicsEditorPresenter.go(view.getContentWindowWorkPanel());
	}

	@Override
	public void loadScreenConfiguration(final String productName, final String productCategory) {

		new GetScreenConfiguration<ScreenConfiguration>(productName, productCategory, webService, new JSONCallback<ScreenConfiguration>(screenConfigurationFactory, ScreenConfiguration.class, Constants.MOCK_SERVER_MODE) {
			@Override
			public void onSuccess(final ScreenConfiguration screenConfig) {
			    if(screenConfig.getText() != null && !screenConfig.getText().isEmpty()) {
			        new GetScreenConfiguration<TextEntries>(productName, productCategory, webService, new JSONCallback<TextEntries>(screenConfigurationFactory, TextEntries.class, Constants.MOCK_SERVER_MODE) {

                        @SuppressWarnings({ "unchecked", "rawtypes" })
                        @Override
                        public void onSuccess(TextEntries textEntries) {
                            screenConfig.setText((List)(textEntries.getText()));
                            for(TextEntry textEntry: textEntries.getText()) {
                                if(textEntry.getValue() != null) {
                                    eventBus.fireEvent(new ConfigChangeEvent(screenConfig));
                                    /*It is Entry Text Type, stop searching*/
                                    return;
                                }
                            }
                            /*if value in text entry is not found, search error texts*/
                            new GetScreenConfiguration<ErrorTexts>(productName, productCategory, webService, new JSONCallback<ErrorTexts>(screenConfigurationFactory, ErrorTexts.class, Constants.MOCK_SERVER_MODE) {

                                @Override
                                public void onSuccess(ErrorTexts errorTexts) {
                                    screenConfig.setText((List)(errorTexts.getText()));
                                    eventBus.fireEvent(new ConfigChangeEvent(screenConfig));
                                }

                                @Override
                                public void onFailure(Throwable throwable,
                                        int statusCode) {
                                    throwable.printStackTrace();
                                    
                                }
                            
                            }).execute();
                        }

                        @Override
                        public void onFailure(Throwable throwable,
                                int statusCode) {
                            
                            // TODO Auto-generated method stub
                        }

			        }).execute();
			    } else {
			        eventBus.fireEvent(new ConfigChangeEvent(screenConfig));
			    }
			}

			@Override
			public void onFailure(Throwable throwable, int statusCode) {
				// TODO Auto-generated method stub
				
			}
		}).execute();
	}

	@Override
	public void go(HasWidgets container) {
		// this.container = container;
		GWT.runAsync(new RunAsyncCallback() {
			public void onFailure(Throwable caught) {
				Window.alert("Code download failed");
			}

			public void onSuccess() {
				view.setProduct(product);
				view.showView();
			}
		});
	}
}
